//
//  RYCHTTPImageQueue.m
//  RaiyiCommon
//
//  Created by zhiwei ma on 12-4-25.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "RYCHTTPImageQueue.h"
#import "RYCHTTPRequest.h"

#define RYCHTTPIMAGEQUEUE_MEMORYCACHE   

#define RYCHTTPIMAGEQUEUEDEBUG

NSString* const RYCHTTPRequestUserInfoKey_Delegate = @"Delegate";

@interface  RYCHTTPImageQueue ()

#ifdef RYCHTTPIMAGEQUEUE_MEMORYCACHE
@property (nonatomic, retain) NSMutableDictionary *dictMemoryCache;

- (void)addToMemoryCache:(NSURL*)url image:(UIImage*)image;
- (UIImage*)imageFromMemoryCache:(NSURL*)url;
#endif

@end

@implementation RYCHTTPImageQueue

- (void)dealloc
{
#ifdef RYCHTTPIMAGEQUEUE_MEMORYCACHE
    self.dictMemoryCache = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
#endif
    [super dealloc];
}

- (id)init
{
    self = [super init];
    if (self)
    {
#ifdef RYCHTTPIMAGEQUEUE_MEMORYCACHE
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNotification:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
#endif
    }
    return self;
}

- (NSInteger)addImage:(NSURL*)aImageURL delegate:(id<RYCHTTPImageQueueDelegate>)aDelegate useCache:(BOOL)aUseCache needCache:(BOOL)aNeedCache
{
#ifdef RYCHTTPIMAGEQUEUEDEBUG
    NSLog(@"%s imageURL= %@",__FUNCTION__,aImageURL);
#endif

    NSInteger reqID = -1;
    if (nil == aImageURL)
    {
        NSLog(@"url is invalid. %@",aImageURL);
        if (aDelegate && [aDelegate respondsToSelector:@selector(didImageFailed:imageURL:)])
        {
            [aDelegate didImageFailed:self imageURL:aImageURL];
        }
    }
    else
    {
#ifdef RYCHTTPIMAGEQUEUE_MEMORYCACHE
        if (aUseCache)
        {
            //内存缓存
            UIImage* image = [self imageFromMemoryCache:aImageURL];
            if (image)
            {
                [aDelegate didImageFinished:self imageURL:aImageURL image:image];
                return 0;
            }
        }
#endif
            
        RYCHTTPRequest* request =  [[[RYCHTTPRequest alloc] initWithURL:aImageURL] autorelease];
        request.delegate = self;
        if (aUseCache)
        {
            //磁盘缓存
            NSData* cacheData = [request.downloadCache cachedResponseDataForURL:request.url];
            NSLog(@"image size= %dk",[cacheData length]/1024);
            if (cacheData)
            {
                UIImage* image = [UIImage imageWithData:cacheData];
                if (image)
                {
                    if (aDelegate)
                    {
#ifdef RYCHTTPIMAGEQUEUE_MEMORYCACHE
                        [self addToMemoryCache:aImageURL image:image];
#endif
                        [request.downloadCache updateExpiryForRequest:request maxAge:60*60*24*2];
                        [aDelegate didImageFinished:self imageURL:aImageURL image:image];
                        return 0;
                    }
                }
                else
                {
                    [request.downloadCache removeCachedDataForRequest:request];
                }
            }
            request.cachePolicy = ASIAskServerIfModifiedWhenStaleCachePolicy;
        }
        else
        {
            request.cachePolicy = ASIDoNotReadFromCacheCachePolicy | ASIFallbackToCacheIfLoadFailsCachePolicy;
        }
        if (aNeedCache)
        {
            request.cacheStoragePolicy = ASICachePermanentlyCacheStoragePolicy;
            request.secondsToCache = 60*60*24*2;//2天
        }
        else
        {
            request.cachePolicy = ASIDoNotWriteToCacheCachePolicy | ASIDoNotReadFromCacheCachePolicy;
        }
        
        if (aDelegate)
        {
            NSDictionary* userInfo = [NSDictionary dictionaryWithObject:aDelegate forKey:RYCHTTPRequestUserInfoKey_Delegate];
            request.userInfo = userInfo;
        }
        reqID = [self addRequest:request];
    }
    
    return reqID;
}

#ifdef RYCHTTPIMAGEQUEUE_MEMORYCACHE
- (void)addToMemoryCache:(NSURL *)url image:(UIImage *)image
{
    if (!url || !image)
    {
        return;
    }
    
    if (!_dictMemoryCache)
    {
        _dictMemoryCache = [[NSMutableDictionary alloc] initWithCapacity:10];
    }
    
    if ([[_dictMemoryCache allKeys] count] > 15)
    {
        NSArray* pre5Keys = [[_dictMemoryCache allKeys] subarrayWithRange:NSMakeRange(0, 5)];
        [_dictMemoryCache removeObjectsForKeys:pre5Keys];
    }
    
    [_dictMemoryCache setObject:image forKey:url];
}

- (UIImage*)imageFromMemoryCache:(NSURL*)url
{
    return [_dictMemoryCache objectForKey:url];
}

- (void)didReceiveNotification:(NSNotification*)notification
{
    if ([notification.name isEqualToString:UIApplicationDidReceiveMemoryWarningNotification])
    {
        self.dictMemoryCache = nil;
    }
}
#endif

#pragma mark ASIHTTPRequestDelegate
- (void)requestFinished:(ASIHTTPRequest*)request
{
    NSURL* imageURL = request.originalURL;
    if (nil == imageURL)
    {
        imageURL = request.url;
    }
#ifdef RYCHTTPIMAGEQUEUEDEBUG
    BOOL useCacheFlag = [request didUseCachedResponse];
    NSLog(@"image finished url=%@",[imageURL absoluteString]);
    NSLog(@"image useCache %d",useCacheFlag);
#endif
    
#if _HTTP_FLOW_RECORD_ALLOW_
    extern long gHTTPFlowRecorder;
    NSInteger curRequestFlow = [[request responseData] length];
    if (NO == useCacheFlag)
    {
        gHTTPFlowRecorder += curRequestFlow;
    }
    NSInteger flowK = gHTTPFlowRecorder/1024;
    NSLog(@"http flow  curRequest=%dB, all=%dK(%dB)", curRequestFlow,flowK,(NSInteger)gHTTPFlowRecorder);
#endif
    
    id delegate = [request.userInfo valueForKey:RYCHTTPRequestUserInfoKey_Delegate];
    if (delegate && [delegate respondsToSelector:@selector(didImageFinished:imageURL:image:)])
    {
        NSData* rspData = [request responseData];
        UIImage* image = nil;
        if (rspData)
        {
            image = [[[UIImage alloc] initWithData:rspData] autorelease];
        }
        if (image)
        {
            [delegate didImageFinished:self imageURL:imageURL image:image];
            
#ifdef RYCHTTPIMAGEQUEUE_MEMORYCACHE
            //添加到内存缓存
            [self addToMemoryCache:imageURL image:image];
#endif
        }
        else
        {
            [delegate didImageFailed:self imageURL:imageURL];
        }
    }
}

- (void)requestFailed:(ASIHTTPRequest*)request
{
    NSURL* imageURL = request.originalURL;
    if (nil == imageURL)
    {
        imageURL = request.url;
    }
#ifdef RYCHTTPIMAGEQUEUEDEBUG
    NSLog(@"image failed url=%@",imageURL);
#endif
    id delegate = [request.userInfo valueForKey:RYCHTTPRequestUserInfoKey_Delegate];
    if (delegate && [(NSObject*)delegate respondsToSelector:@selector(didImageFailed:imageURL:)])
    {
        [delegate didImageFailed:self imageURL:imageURL];
    }
}

@end
